# 106. 从中序与后序遍历序列构造二叉树

// 根据一棵树的中序遍历与后序遍历构造二叉树。
// 注意:
// 你可以假设树中没有重复的元素。
// 例如,给出
// 中序遍历 inorder = [9,3,15,20,7]
// 后序遍历 postorder = [9,15,7,20,3]
// 返回如下的二叉树:
//     3
//    / \
//   9  20
//     /  \
//    15   7
// ```js
// // 后序遍历的数组最后一个元素代表的即为根节点

// // 中序遍历的顺序是每次遍历左孩子,再遍历根节点,最后遍历右孩子。
// // 后序遍历的顺序是每次遍历左孩子,再遍历右孩子,最后遍历根节点。
// void inorder(TreeNode* root) {
//   if (root == nullptr) {
//       return;
//   }
//   inorder(root->left);
//   ans.push_back(root->val);
//   inorder(root->right);
// }
// // 后序遍历
// void postorder(TreeNode* root) {
//   if (root == nullptr) {
//       return;
//   }
//   postorder(root->left);
//   postorder(root->right);
//   ans.push_back(root->val);
// }
// ```;
function TreeNode(val, left, right) {
  this.val = val === undefined ? 0 : val;
  this.left = left === undefined ? null : left;
  this.right = right === undefined ? null : right;
}
var buildTree = function(inorder, postorder) {
  let posIndex; // 表示后序遍历最后的index 后序遍历的数组最后一个元素代表的即为根节点

  const map = new Map(); // 缓存中序遍历的哈希表, 用于通过后序遍历的val找到对应在中序遍历的索引

  inorder.forEach((val, index) => {
    map.set(val, index);
  });

  function deep(in_left, in_right) {
    if (in_left > in_right) return null; // 表示没有节点可以构造了

    const root_val = postorder[posIndex];
    const in_index = map.get(root_val); // 后序遍历最后的值在中序遍历中所在的索引, 也是表示根节点
    const root = new TreeNode(root_val); // 生成根节点

    posIndex--; // 更新 后序遍历最后的索引

    root.right = deep(in_index + 1, in_right); // 生成右子树
    root.left = deep(in_left, in_index - 1); // 生成左子树

    return root;
  }

  posIndex = postorder.length - 1;

  return deep(0, inorder.length - 1);
};

console.log(buildTree([9, 3, 15, 20, 7], [9, 15, 7, 20, 3]));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Last Updated: 6/27/2023, 7:40:45 PM